﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using System.IO;
using StripeOne.Core.Cache;
using StripeOne.Core.Log;
using StripeOne.Core.Tools;

namespace StripeOne.Blog.Base.Configuration
{
    public class Instances : StripeOneXml
    {
        public Instances(string section) : base("Instances", section) { }

        public static List<Instance> InstanceList
        {
            get
            {
                var cacheKey = "StripeOneInstances_AllInstances";
                return (List<Instance>)new StripeOneCache().AutoCache<List<Instance>>(cacheKey, CacheTimes.Default.Instance, () => GetInstancesNoCache()).Value;
            }
        }

        private static List<Instance> GetInstancesNoCache()
        {
            var result = new List<Instance>();
            var cacheKey = "StripeOneInstances_GetInstances_Xml";
            XDocument xml = StripeOneXml.Load("Instances", false, false, CacheTimes.Default.Instance, cacheKey);

            foreach (var domain in xml.Descendants("instance"))
            {
                var domainAttribute = domain.Attribute("domain").Value;

                var data = new Instance();
                data.Domain = domainAttribute;
                data.Country = domain.Element("country").Value;
                data.Dictionary = domain.Element("dictionary").Value;
                data.DateFormat = domain.Element("dateFormat").Value;
                data.Language = domain.Element("language").Value;

                result.Add(data);
            }

            return result;
        }

        public static Instance Default
        {
            get
            {
                return InstanceList.FirstOrDefault();
            }
        }

        public static Instance Current
        {
            get
            {
                return SetInstance();
            }
        }

        public static Instance SetInstance()
        {
            try
            {
                var cache = new StripeOneCache();
                string cacheKey = "StripeOneInstances_SetInstance_" + GetCurrentHost();
                return (Instance)cache.AutoCache<Instance>(cacheKey, CacheTimes.Default.Instance, () => SetInstanceNoCache()).Value;
            }
            catch (Exception ex)
            {
                StripeOneLog.Exception(ex);
                return null;
            }
        }

        private static Instance SetInstanceNoCache()
        {
            var cache = new StripeOneCache();
            var data = new Instance();
            var myInstance = Instances.InstanceList.FirstOrDefault(i => i.Domain.ToLower() == GetCurrentHost());
            if (myInstance != null)
            {
                data = myInstance;
            }
            else if (Instances.Default != null)
            {
                StripeOneLog.Warning("Using Default Instance (the first of configuration file).");
                data = Instances.Default;
            }
            else
            {
                StripeOneLog.Warning("No Instance loaded, check Instances.xml file.");
                return null;
            }

            return data;
        }

        public static string GetCurrentHost()
        {
            string host = String.Empty;
            try
            {
                host = HttpContext.Current.Request.Url.Host.ToLower();
            }
            catch(Exception ex)
            {
                StripeOneLog.Exception(ex);
            }
            return host;
        }
    }

    public class Instance
    {
        public string Domain { get; set; }
        public string Country { get; set; }
        public string Dictionary { get; set; }
        public string DateFormat { get; set; }
        public string Language { get; set; }

        public Instance() { }
    }
}